import { Placement, Options, Offsets, Instance, createPopper } from "@popperjs/core"
import { Prop, Vue, Watch } from "vue-property-decorator";

export default class Popper extends Vue {
    @Prop({ type: Boolean, default: false }) value!: boolean
    @Prop({ default: "bottom" }) placement!: Placement
    @Prop({ type: Number, default: 5 }) boundariesPadding!: number
    @Prop() offset!: Offsets
    @Prop(HTMLElement) reference!: HTMLElement;
    @Prop(HTMLElement) popper!: HTMLElement;
    @Prop(String) transition!: string;
    @Prop({
        default() {
            return {
                modifiers: {
                    computeStyle: {
                        gpuAcceleration: false,
                    },
                    preventOverflow: {
                        boundariesElement: 'window'
                    }
                }
            };
        }
    }) options!: Options
    popperJS!: Instance
    isServer = false;
    visible = this.value
    handleIndexIncrease?: Function

    @Watch("value", { immediate: true })
    OnValueChange(val: boolean) {
        this.visible = val;
        // F this.$emit('input', val);

        if (val) {
            if (this.handleIndexIncrease)
                this.handleIndexIncrease();  // just use for Poptip
            this.updatePopper();
            this.$emit('on-popper-show');
        } else {
            this.$emit('on-popper-hide');
        }
        this.$emit('input', val);
    }


    createPopper() {
        if (this.isServer) return;
        if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
            return;
        }

        const options = this.options;
        const popper = this.popper || this.$refs.popper;
        const reference = this.reference || this.$refs.reference;

        if (!popper || !reference) return;

        if (this.popperJS && Object.prototype.hasOwnProperty.call(this.popperJS, "destroy")) {
            this.popperJS.destroy();
        }

        if (this.offset) {
            options.modifiers.push({ name: "", options: this.offset })
        }

        options.onFirstUpdate = () => {
            this.$nextTick(this.updatePopper);
            this.$emit('created', this);
        };

        this.popperJS = createPopper(reference, popper, options);

    }
    updatePopper() {
        if (this.isServer) return;
        this.popperJS ? this.popperJS.update() : this.createPopper();
    }
    doDestroy() {
        if (this.isServer) return;
        if (this.visible) return;
        this.popperJS.destroy();
        // this.popperJS = null;
    }

    updated() {
        this.$nextTick(() => this.updatePopper());

    }
    beforeDestroy() {
        if (this.isServer) return;
        if (this.popperJS) {
            this.popperJS.destroy();
        }
    }
}